package com.example.makerspace.service.impl;


import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.example.makerspace.config.PhoneCodeConfig;
import com.example.makerspace.dao.*;
import com.example.makerspace.domain.*;
import com.example.makerspace.dto.*;
import com.example.makerspace.enums.ResultCodeEnum;
import com.example.makerspace.enums.UserRoleEnum;
import com.example.makerspace.manager.UserManager;
import com.example.makerspace.service.LoginService;
import com.example.makerspace.utils.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.example.makerspace.domain.UserDO.ACTIVE_STATUS;


/**
 * @author River
 * @version 1.0
 * @date 2023/9/26 10:37
 * @description:
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private UserDAO userDAO;

    @Resource
    private UserManager userManager;

    @Value("${spring.mail.username}")
    private String from;   // 邮件发送人

    @Resource
    private SingInRecordDAO singInRecordDAO;

    @Resource
    private IntegralTasksDAO integralTasksDAO;

    @Resource
    private  UsersOnlineDAO usersOnlineDAO;

    @Resource
    private TaskFinishDAO taskFinishDAO;


    @Resource
    private TaskTagDAO taskTagDAO;


    @Resource
    private PhoneCodeConfig phoneCodeConfig;

    @Resource
    private  UserLoginLogsDAO userLoginLogsDAO;

    @Resource
    private RedisUtils redisUtils;

    @Override
    public Result sendEmail(ValidateCodeDTO validateCodeDTO) {
        String email = validateCodeDTO.getEmail();
        String validateCode = ValidateCodeUtils.generateCode(6);
        String subject = "网信创客验证码";
        String text = "验证码为: " + validateCode + ",五分钟内有效，请妥善保管!";
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(from);
        simpleMailMessage.setTo(email);
        simpleMailMessage.setSubject(subject);
        simpleMailMessage.setText(text);
        javaMailSender.send(simpleMailMessage);
        redisTemplate.opsForValue().set(email, validateCode.toLowerCase(), 5, TimeUnit.MINUTES);
        return Result.success();
    }

    @Override
    public Result CaptchaCode(CaptchaCodeDTO captchaCodeDTO) {
        String validateCode = ValidateCodeUtils.generateCodeNumber(4);
        String msg = MessageUtils.sendCaptcha(captchaCodeDTO.getPhone(),validateCode);
        if(msg.equals("OK")){
                redisTemplate.opsForValue().set(captchaCodeDTO.getPhone(), validateCode, 5, TimeUnit.MINUTES);
                return  Result.success(ResultCodeEnum.Message_SUCCESS);
            }
        return  Result.error(ResultCodeEnum.Message_Error,msg);
    }

    @Override
    public Result register(RegistrationDTO registrationDTO) {
        String password = registrationDTO.getPassword();
        String verifyPassword = registrationDTO.getVerifyPassword();
        String username = registrationDTO.getUsername();
        UserDO older = userDAO.selectByUsername(username);
        if(older!=null){
            return  Result.error(ResultCodeEnum.Have_REGISTER);
        }
        String validateCode = registrationDTO.getValidateCode();
        String code = (String) redisTemplate.opsForValue().get(username);
        if(!password.equals(verifyPassword) && !validateCode.equals(code)){
            return Result.error(ResultCodeEnum.VALIDATE_CODE_AND_VERIFY_PASSWORD_NOT_MATCH);
        } else if (!password.equals(verifyPassword)) {
            return Result.error(ResultCodeEnum.VERIFY_PASSWORD_NOT_MATCH);
        } else if (!validateCode.equals(code)) {
            return Result.error(ResultCodeEnum.ERROR_VALIDATE_CODE);
        }
        if(!registrationDTO.getPassword().equals(registrationDTO.getVerifyPassword())){
            return Result.error(ResultCodeEnum.VERIFY_PASSWORD_NOT_MATCH);
        }
        UserDO userDO = new UserDO();
        userDO.setUsername(username);
        userDO.setPassword(DigestUtil.sha256Hex(password));
        userDO.setRole(UserRoleEnum.NORMAL.getRole());
        userDO.setNickname(NameUtils.getName());
        userDO.setStatus(ACTIVE_STATUS);
        SingInRecordDO singInRecordDO = new SingInRecordDO();
        singInRecordDO.setUsername(userDO.getUsername());
        singInRecordDO.setContinueNumber(0);
        singInRecordDAO.insert(singInRecordDO);
        List<TaskTagDO> taskTagDOS = taskTagDAO.selectAll();
        for(TaskTagDO taskTagDO:taskTagDOS){
            TaskFinishDO taskFinishDO = new TaskFinishDO();
            taskFinishDO.setTaskId(taskTagDO.getId());
            taskFinishDO.setUsername(userDO.getUsername());
            taskFinishDAO.insert(taskFinishDO);
        }
        //userDO.setAvatar("https://119.45.199.13:8080/static/resource/3x.png");
        userDO.setAvatar("https://nism.ytcata.com:443/static/resource/18192396039/默认头像.svg");
        userDO.setBackground("https://img.zcool.cn/community/01d3275be6ab50a80121ab5deed64f.jpg@2o.jpg");
        return userManager.createUser(userDO);
    }

    @Override
    public Result login(HttpServletRequest request, LoginDTO loginDTO) {
        String clientIp = IpUtils.getClientIp(request);
        String browser = request.getHeader("user-agent");
        String oldToken = request.getHeader("token");
        if(JwtUtils.checkToken(oldToken)){
            return Result.error(ResultCodeEnum.ALREADY_LOGIN);
        }
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();
        UserDO userDO = userDAO.selectByUsername(username);
        HttpSession session = request.getSession();
        session.setAttribute("user",userDO);
        if(userDO == null){
            return Result.error(ResultCodeEnum.USER_DONT_EXIST);
        }
        if(userDO.getStatus().equals(0)){
            return Result.error(ResultCodeEnum.User_Disable);
        }
        String shaPassword = DigestUtil.sha256Hex(password);
        if(!userDO.getPassword().equals(shaPassword)){
            return Result.error(ResultCodeEnum.LOGIN_ERROR);
        }
        UserLoginLogsDO userLoginLogsDO = new UserLoginLogsDO();
        userLoginLogsDO.setUsername(loginDTO.getUsername());
        userLoginLogsDO.setIpAddress(clientIp);
        userLoginLogsDO.setBrowser(browser);
        userLoginLogsDAO.insert(userLoginLogsDO);
        String token = JwtUtils.createToken(userDO.getId(), userDO.getUsername(), userDO.getRole());
        String loginKey=userDO.getUsername();
        redisUtils.setEx(loginKey,token, 60  * 60 * 24L,TimeUnit.SECONDS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("token", token);
        jsonObject.put("username", userDO.getUsername());
        jsonObject.put("id", userDO.getId());
        jsonObject.put("role", userDO.getRole());
        jsonObject.put("nickname", userDO.getNickname());
        jsonObject.put("status", userDO.getStatus());
        return Result.success(jsonObject);
    }

    @Override
    public Result login1(RegistrationDTO registrationDTO, HttpServletRequest request) {
        String username = registrationDTO.getUsername();
        UserDO userDO = userDAO.selectByUsername(username);
        HttpSession session = request.getSession();
        session.setAttribute("user",userDO);
        if(userDO==null){
            return  Result.error(ResultCodeEnum.NO_REGISTER);
        }
        String validateCode = registrationDTO.getValidateCode();
        String code = (String) redisTemplate.opsForValue().get(username);
        if (!validateCode.equals(code)) {
            return Result.error(ResultCodeEnum.ERROR_VALIDATE_CODE);
        }
        String token = JwtUtils.createToken(userDO.getId(), userDO.getUsername(), userDO.getRole());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("token", token);
        jsonObject.put("username", userDO.getUsername());
        jsonObject.put("id", userDO.getId());
        jsonObject.put("role", userDO.getRole());
        jsonObject.put("nickname", userDO.getNickname());
        jsonObject.put("status", userDO.getStatus());
        return Result.success(jsonObject);
    }

    @Override
    public Result loginCheck(String username) {
        List<UsersOnlineDO> usersOnlineDOS = usersOnlineDAO.selectByUserName(username);
        if(CollectionUtils.isEmpty(usersOnlineDOS)){
            return  Result.success("没有用户登入");
        }
       return  Result.success(ResultCodeEnum.ALREADY_LOGIN);

    }

    @Override
    public Result forgetPassword(RegistrationDTO registrationDTO) {
        String password = registrationDTO.getPassword();
        String verifyPassword = registrationDTO.getVerifyPassword();
        String username = registrationDTO.getUsername();
        String validateCode = registrationDTO.getValidateCode().toLowerCase();
        String code = (String) redisTemplate.opsForValue().get(username);
        if(!password.equals(verifyPassword) && !validateCode.equals(code)){
            return Result.error(ResultCodeEnum.VALIDATE_CODE_AND_VERIFY_PASSWORD_NOT_MATCH);
        } else if (!password.equals(verifyPassword)) {
            return Result.error(ResultCodeEnum.VERIFY_PASSWORD_NOT_MATCH);
        } else if (!validateCode.equals(code)) {
            return Result.error(ResultCodeEnum.ERROR_VALIDATE_CODE);
        }
        registrationDTO.setPassword(password);
        return userManager.forgetPassword(registrationDTO);
    }
}
